bitkeeper revision 1.1159.212.118 (420808adQbNXWTSEhY2Rqu5ALqDF5Q)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Tue, 8 Feb 2005 00:32:45 +0000 (00:32 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Tue, 8 Feb 2005 00:32:45 +0000 (00:32 +0000)
- Detect the CPU speed automatically, rather than having the user
  specify a ips in bochsrc. The user can still specify it to override
  the auto-detected value.

- Care should be taken to make sure that tsc_per_bx_tick is not too
  small or too big. Otherwise, numerical precision issues may result
  in the wrong calculation of elapsed time

Signed-off-by: Edwin Zhai <edwin.zhai@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
Signed-off-by: ian@xensource.com
tools/examples/bochsrc
tools/ioemu/include/pc_system.h
tools/ioemu/iodev/cpu.cc
tools/ioemu/iodev/pc_system.cc

index 860c5499eb7a37dc1f4ccd9070300e41dcf1d021..8075a7658b3e78f6c43c439e5bf57dc5430d32c5 100644 (file)
@@ -16,4 +16,3 @@ error: action=report
 panic: action=ask
 
 mouse: enabled=0
-ips: 1500000
index c35c35bf52feb960bbfc00b8d000a059f7c078c3..c8ea6645779f9543c7f65816db1f5e823647ff6e 100644 (file)
@@ -45,6 +45,13 @@ BOCHSAPI extern class bx_pc_system_c bx_pc_system;
 extern double m_ips;
 #endif
 
+#ifdef BX_USE_VMX
+extern unsigned int tsc_per_bx_tick;
+
+#define rdtscll(val) \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+#endif
+
 class BOCHSAPI bx_pc_system_c : private logfunctions {
 private:
 
@@ -87,6 +94,26 @@ private:
   double     m_ips; // Millions of Instructions Per Second
 #endif
 
+#ifdef BX_USE_VMX
+  static Bit64s get_clock(void) {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000LL + tv.tv_usec;
+    }
+
+  static Bit64u cpu_calibrate_ticks(void) {
+    Bit64s usec, t1, t2;
+
+    usec = get_clock();
+    rdtscll(t1);
+
+    usleep(50 * 1000);
+    usec = get_clock() - usec;
+    rdtscll(t2);
+
+    return (((t2 - t1) * 1000000LL + (usec >> 1)) / usec);
+    }
+#endif
   // This handler is called when the function which decrements the clock
   // ticks finds that an event has occurred.
   void   countdownEvent(void);
index 11e761d7749e42aefb01903c4263d6ae0e4dda60..71853afa61ebad445c74b8867847684a6c8d3382 100644 (file)
@@ -167,9 +167,6 @@ bx_cpu_c::timer_handler(void)
 #define rdtscl(low) \
      __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
 
-#define rdtscll(val) \
-     __asm__ __volatile__("rdtsc" : "=A" (val))
-
 void
 bx_cpu_c::cpu_loop(int max_instr_count)
 {
@@ -211,9 +208,9 @@ bx_cpu_c::cpu_loop(int max_instr_count)
 #endif
 
                if (t2 <= t1)
-                       BX_TICKN((t2 + ULONGLONG_MAX - t1));
+                       BX_TICKN((t2 + ULONGLONG_MAX - t1) / tsc_per_bx_tick);
                else
-                       BX_TICKN((t2 - t1));
+                       BX_TICKN((t2 - t1) / tsc_per_bx_tick);
                t1 = t2;
 
                timer_handler();
index 1b58fe775f6aae1165ec7fe1e911b25d271f44cc..de34d9914b203884b225ba66d9d8539c86c3ce73 100644 (file)
@@ -44,6 +44,10 @@ unsigned long ips_count=0;
 double     m_ips; // Millions of Instructions Per Second
 #endif
 
+#ifdef BX_USE_VMX
+unsigned int tsc_per_bx_tick;
+#endif
+
 // Option for turning off BX_TIMER_DEBUG?
 // Check out m_ips and ips
 
@@ -98,6 +102,16 @@ bx_pc_system_c::init_ips(Bit32u ips)
   a20_mask   = 0xffffffff;
 #endif
 
+#ifdef BX_USE_VMX
+  Bit64u phy_cpu_freq = cpu_calibrate_ticks();
+  if (ips == 500000) {  //default ips: we use fixed scaling factor to calulate ips
+    tsc_per_bx_tick = 2000;
+    ips = phy_cpu_freq / tsc_per_bx_tick;
+  } else  //use uesr defined ips to calulate factor
+    tsc_per_bx_tick = ((phy_cpu_freq + (ips>>1)) / ips);
+#endif
+
   // parameter 'ips' is the processor speed in Instructions-Per-Second
   m_ips = double(ips) / 1000000.0L;